#include "udpserver.h"
#include <QDebug>
#include "log.h"
#include "log.cpp"

udpserver::udpserver(QObject *parent) : QObject(parent)
{
    // 检查是否已有默认连接
    if (QSqlDatabase::contains("qt_sql_default_connection")) {
        qDebug() << "使用已存在的数据库连接";
    } else {
        QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
        db.setHostName("127.0.0.1");
        db.setPort(3306);
        db.setDatabaseName("serialport");
        db.setUserName("root");
        db.setPassword("123456");

        if (db.open()) {
            qDebug() << "数据库打开成功";
        } else {
            qDebug() << "数据库打开失败:" << db.lastError().text();
        }
    }

    this->serviceConfig = this->readDatabase();
    for (auto item = this->serviceConfig.begin(); item != this->serviceConfig.end(); item++) {
        if (item.value().at(4).toString() == "3") { // protocol字段为3表示UDP
            this->setupUdpService(item.key(), item.value());
        }
    }
}

udpserver::~udpserver()
{
    // 清理资源
    for (auto& instance : ports) {
        if (instance.udpSocket) {
            instance.udpSocket->close();
            delete instance.udpSocket;
        }
    }
}

QMap<int, QVector<QVariant>> udpserver::readDatabase()
{
    QMap<int, QVector<QVariant>> dataContainer;
    QSqlDatabase db = QSqlDatabase::database();
    QSqlQuery query(db);

    QString sqlQuery = "SELECT port_no, cr_explained, if_explained, links_num, protocol, peerhost, peerport, diaconnect, freetime FROM port";

    if (!query.prepare(sqlQuery)) {
        qDebug() << "Query preparation failed:" << query.lastError().text();
        return dataContainer;
    }

    if (!query.exec()) {
        qDebug() << "Query execution failed:" << query.lastError().text();
        return dataContainer;
    }

    QSqlRecord record = query.record();
    int columnCount = record.count();
    int dbIndex = 0;

    while (query.next()) {
        QVector<QVariant> rowData;
        for (int i = 0; i < columnCount; ++i) {
            rowData.append(query.value(i));
        }
        dataContainer[dbIndex] = rowData;
        qDebug() << "读取数据库记录" << dbIndex << ": port_no =" << rowData.at(0).toInt();
        dbIndex++;
    }

    return dataContainer;
}

void udpserver::setupUdpService(int dbIndex, QVector<QVariant> config)
{
    PortInstance instance;
    instance.type = "Udp";
    instance.dbIndex = dbIndex;
    instance.localPort = config.at(0).toInt();    // port_no
    instance.targetHost = config.at(5).toString(); // peerhost
    instance.targetPort = config.at(6).toInt();   // peerport

    instance.udpSocket = new QUdpSocket(this);

<<<<<<< HEAD
    if (!instance.udpSocket->bind(QHostAddress::Any, instance.localPort)) {
        qDebug() << "UDP绑定成功，端口" << instance.localPort << ":" << instance.udpSocket->errorString();
=======
    quint16 localPort = row.at(0).toInt(); // port_no
    if (!instance.udpSocket->bind(QHostAddress::Any, localPort))
    {
        m_logger->writefile(QString("UDP绑定成功,端口：%1").arg(QString::number(localPort)));
//        qDebug() << "UDP绑定成功，端口" << localPort << ":" << instance.udpSocket->errorString();
>>>>>>> bd87e5561ea1c8d412e8d2a4f55b15f5140bd2a5
        delete instance.udpSocket;
        return;
    }

    // 记录数据库索引到端口列表索引的映射
    int portIndex = ports.size();
    ports.append(instance);
    dbIndexToPortIndex[dbIndex] = portIndex;
    localPortToIndex[instance.localPort] = portIndex;

    // 连接信号槽处理接收到的数据
    connect(instance.udpSocket, &QUdpSocket::readyRead, [this, dbIndex]() {
        if (!dbIndexToPortIndex.contains(dbIndex)) {
            qDebug() << "无效的数据库索引:" << dbIndex;
            return;
        }

        PortInstance &instance = ports[dbIndexToPortIndex[dbIndex]];
        while (instance.udpSocket->hasPendingDatagrams()) {
            QByteArray datagram;
            datagram.resize(instance.udpSocket->pendingDatagramSize());
            QHostAddress sender;
            quint16 senderPort;
            instance.udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);

<<<<<<< HEAD
            qDebug() << "[UDP] 从" << sender.toString() << ":" << senderPort
                     << "接收数据，本地端口:" << instance.udpSocket->localPort()
                     << "数据:" << datagram;

            // 新增：自动回复功能
            QByteArray response = "收到数据:HiHiHiHi  l get it !!! " ;
            qint64 bytesWritten = instance.udpSocket->writeDatagram(
                response, sender, senderPort);

            if (bytesWritten == -1) {
                qDebug() << "回复失败:" << instance.udpSocket->errorString();
            } else {
                qDebug() << "已回复" << bytesWritten << "字节到" << sender.toString() << ":" << "senderPort111111";
            }

=======
            m_logger->writefile(QString("UDP从%1，端口：%2收到数据:%3").arg(sender.toString()).arg(senderPort).arg(QString::fromUtf8(datagram)));


//            qDebug() << "[UDP] 从" << sender.toString() << ":" << senderPort
//                     << "接收数据，本地端口:" << instance.udpSocket->localPort()
//                     << "数据:" << datagram;
            emit Udpsever(dbIndex, datagram);
>>>>>>> bd87e5561ea1c8d412e8d2a4f55b15f5140bd2a5
        }
    });


    qDebug() << "UDP服务已启动，本地端口:" << instance.localPort
             << "，目标:" << instance.targetHost << ":" << instance.targetPort
             << "，数据库索引:" << dbIndex;
}

void udpserver::onSerialrDataReceived(int dbIndex, const QByteArray &data)
{
    if (!dbIndexToPortIndex.contains(dbIndex)) {
        qDebug() << "[Udp] 无效的数据库索引:" << dbIndex;
        return;
    }

    int portIndex = dbIndexToPortIndex[dbIndex];
    PortInstance &instance = ports[portIndex];

    if (instance.type == "Udp" && instance.udpSocket) {
        qint64 bytesWritten = instance.udpSocket->writeDatagram(
            data, QHostAddress(instance.targetHost), instance.targetPort);

<<<<<<< HEAD
        if (bytesWritten == -1) {
            qDebug() << "[Udp] 发送数据失败，目标:" << instance.targetHost << ":" << instance.targetPort
                     << "，本地端口:" << instance.udpSocket->localPort()
                     << "，错误:" << instance.udpSocket->errorString();
        } else {
            qDebug() << "[Udp] 成功发送" << bytesWritten << "字节，目标:" << instance.targetHost << ":" << instance.targetPort
                     << "，本地端口:" << instance.udpSocket->localPort();
=======
        if (bytesWritten == -1)
        {
            qDebug() << "[Udp] 发送数据失败，目标:" << targetHost << ":" << targetPort
                     << "，本地端口:" << instance.udpSocket->localPort()
                     << "，错误:" << instance.udpSocket->errorString();
        }
        else
        {
            m_logger->writefile(
                QString("UDP成功发送%1，目标：%2")
                    .arg(bytesWritten)
                    .arg(targetHost));
//            qDebug() << "[Udp] 成功发送" << bytesWritten << "字节，目标:" << targetHost << ":" << targetPort
//                     << "，本地端口:" << instance.udpSocket->localPort();
>>>>>>> bd87e5561ea1c8d412e8d2a4f55b15f5140bd2a5
        }
    }
}

bool udpserver::isDatabaseOpen() const
{
    QSqlDatabase db = QSqlDatabase::database();
    return db.isOpen();
}

// 通过数据库索引发送数据
void udpserver::sendData(int dbIndex, const QByteArray& data)
{
    if (!dbIndexToPortIndex.contains(dbIndex)) {
        qDebug() << "[Udp] 无效的数据库索引:" << dbIndex;
        return;
    }

    int portIndex = dbIndexToPortIndex[dbIndex];
    PortInstance &instance = ports[portIndex];

    if (instance.type == "Udp" && instance.udpSocket) {
        qint64 bytesWritten = instance.udpSocket->writeDatagram(
            data, QHostAddress(instance.targetHost), instance.targetPort);

        if (bytesWritten == -1) {
            qDebug() << "[Udp] 发送数据失败，目标:" << instance.targetHost << ":" << instance.targetPort
                     << "，本地端口:" << instance.udpSocket->localPort()
                     << "，错误:" << instance.udpSocket->errorString();
        } else {
            qDebug() << "[Udp] 成功发送" << bytesWritten << "字节，目标:" << instance.targetHost << ":" << instance.targetPort
                     << "，本地端口:" << instance.udpSocket->localPort();
        }
    }
}

// 不指定源端口发送数据
void udpserver::sendData(const QString& targetIp, quint16 targetPort, const QByteArray& data)
{
    QUdpSocket tempSocket;
    qint64 bytesWritten = tempSocket.writeDatagram(data, QHostAddress(targetIp), targetPort);

    if (bytesWritten == -1) {
        qDebug() << "发送UDP数据失败:" << tempSocket.errorString();
    } else {
        qDebug() << "成功发送" << bytesWritten << "字节到" << targetIp << ":" << targetPort;
    }
}

// 指定源端口发送数据
void udpserver::sendData(const QString& targetIp, quint16 targetPort, quint16 sourcePort, const QByteArray& data)
{
    if (!localPortToIndex.contains(sourcePort)) {
        qDebug() << "错误：此类没有监听（因此无法作为源）端口" << sourcePort;

        // 回退到临时套接字发送
        QUdpSocket tempSocket;
        qint64 bytesWritten = tempSocket.writeDatagram(data, QHostAddress(targetIp), targetPort);

        if (bytesWritten == -1) {
            qDebug() << "使用临时套接字发送UDP数据失败:" << tempSocket.errorString();
        } else {
            qDebug() << "使用临时套接字成功发送" << bytesWritten << "字节到" << targetIp << ":" << targetPort;
        }
        return;
    }

    int portIndex = localPortToIndex[sourcePort];
    PortInstance &instance = ports[portIndex];

    if (instance.udpSocket) {
        qint64 bytesWritten = instance.udpSocket->writeDatagram(data, QHostAddress(targetIp), targetPort);
        if (bytesWritten == -1) {
            qDebug() << "从端口" << sourcePort << "发送UDP数据失败:" << instance.udpSocket->errorString();
        } else {
            qDebug() << "从端口" << sourcePort << "成功发送" << bytesWritten << "字节到" << targetIp << ":" << targetPort;
        }
    } else {
        qDebug() << "错误：端口" << sourcePort << "的socket实例为空";
    }
}
